Implement for cached themes.
authorMatthias Clasen <mclasen@redhat.com>
Thu, 21 Oct 2004 18:44:08 +0000 (18:44 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Thu, 21 Oct 2004 18:44:08 +0000 (18:44 +0000)
2004-10-21  Matthias Clasen  <mclasen@redhat.com>

* gtk/gtkicontheme.c (gtk_icon_theme_has_icon): Implement for
cached themes.

* gtk/gtkiconcache.h:
* gtk/gtkiconcache.c (_gtk_icon_cache_has_icon): New function.

* gtk/updateiconcache.c (scan_directory): Don't skip .icon
files which are listed before their images.
(foreach_remove_func): Instead filter lonely .icon files out
here.

* gtk/gtkicontheme.c (theme_dir_get_icon_suffix): Filter out
the HAS_ICON_FILE flag.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkiconcache.c
gtk/gtkiconcache.h
gtk/gtkicontheme.c
gtk/updateiconcache.c

index 00a191de9f615a537dffc1d94b590e03f5a5ec34..1313293b745056520354f8d794d385fecdd49df3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2004-10-21  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkicontheme.c (gtk_icon_theme_has_icon): Implement for
+       cached themes.
+
+       * gtk/gtkiconcache.h: 
+       * gtk/gtkiconcache.c (_gtk_icon_cache_has_icon): New function.
+
+       * gtk/updateiconcache.c (scan_directory): Don't skip .icon 
+       files which are listed before their images.
+       (foreach_remove_func): Instead filter lonely .icon files out
+       here.
+
+       * gtk/gtkicontheme.c (theme_dir_get_icon_suffix): Filter out
+       the HAS_ICON_FILE flag.
+
 2004-10-21  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkiconcache.c: Make it compile without mmap() and
index 00a191de9f615a537dffc1d94b590e03f5a5ec34..1313293b745056520354f8d794d385fecdd49df3 100644 (file)
@@ -1,3 +1,19 @@
+2004-10-21  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkicontheme.c (gtk_icon_theme_has_icon): Implement for
+       cached themes.
+
+       * gtk/gtkiconcache.h: 
+       * gtk/gtkiconcache.c (_gtk_icon_cache_has_icon): New function.
+
+       * gtk/updateiconcache.c (scan_directory): Don't skip .icon 
+       files which are listed before their images.
+       (foreach_remove_func): Instead filter lonely .icon files out
+       here.
+
+       * gtk/gtkicontheme.c (theme_dir_get_icon_suffix): Filter out
+       the HAS_ICON_FILE flag.
+
 2004-10-21  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkiconcache.c: Make it compile without mmap() and
index 00a191de9f615a537dffc1d94b590e03f5a5ec34..1313293b745056520354f8d794d385fecdd49df3 100644 (file)
@@ -1,3 +1,19 @@
+2004-10-21  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkicontheme.c (gtk_icon_theme_has_icon): Implement for
+       cached themes.
+
+       * gtk/gtkiconcache.h: 
+       * gtk/gtkiconcache.c (_gtk_icon_cache_has_icon): New function.
+
+       * gtk/updateiconcache.c (scan_directory): Don't skip .icon 
+       files which are listed before their images.
+       (foreach_remove_func): Instead filter lonely .icon files out
+       here.
+
+       * gtk/gtkicontheme.c (theme_dir_get_icon_suffix): Filter out
+       the HAS_ICON_FILE flag.
+
 2004-10-21  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkiconcache.c: Make it compile without mmap() and
index 00a191de9f615a537dffc1d94b590e03f5a5ec34..1313293b745056520354f8d794d385fecdd49df3 100644 (file)
@@ -1,3 +1,19 @@
+2004-10-21  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkicontheme.c (gtk_icon_theme_has_icon): Implement for
+       cached themes.
+
+       * gtk/gtkiconcache.h: 
+       * gtk/gtkiconcache.c (_gtk_icon_cache_has_icon): New function.
+
+       * gtk/updateiconcache.c (scan_directory): Don't skip .icon 
+       files which are listed before their images.
+       (foreach_remove_func): Instead filter lonely .icon files out
+       here.
+
+       * gtk/gtkicontheme.c (theme_dir_get_icon_suffix): Filter out
+       the HAS_ICON_FILE flag.
+
 2004-10-21  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkiconcache.c: Make it compile without mmap() and
index 7aca03eac09c0542af8e93d3d9338b022d15e6b0..5175787c7c9dac6fa08e536ebe7c18476a3f715b 100644 (file)
@@ -50,7 +50,6 @@ GtkIconCache *
 _gtk_icon_cache_ref (GtkIconCache *cache)
 {
   cache->ref_count ++;
-
   return cache;
 }
 
@@ -141,7 +140,6 @@ _gtk_icon_cache_new_for_path (const gchar *path)
   cache->ref_count = 1;
   cache->buffer = buffer;
   cache->size = st.st_size;
-  
  done:
   g_free (cache_filename);  
   close (fd);
@@ -282,6 +280,36 @@ _gtk_icon_cache_add_icons (GtkIconCache *cache,
 
          chain_offset = GET_UINT32 (cache->buffer, chain_offset);
        }
-    }
+    }  
+}
+
+gboolean
+_gtk_icon_cache_has_icon (GtkIconCache *cache,
+                         const gchar  *icon_name)
+{
+  guint32 hash_offset;
+  guint32 n_buckets;
+  guint32 chain_offset;
+  gint hash;
   
+  hash_offset = GET_UINT32 (cache->buffer, 4);
+  n_buckets = GET_UINT32 (cache->buffer, hash_offset);
+
+  hash = icon_name_hash (icon_name) % n_buckets;
+
+  chain_offset = GET_UINT32 (cache->buffer, hash_offset + 4 + 4 * hash);
+  while (chain_offset != 0xffffffff)
+    {
+      guint32 name_offset = GET_UINT32 (cache->buffer, chain_offset + 4);
+      gchar *name = cache->buffer + name_offset;
+
+      if (strcmp (name, icon_name) == 0)
+       return TRUE;
+         
+      chain_offset = GET_UINT32 (cache->buffer, chain_offset);
+    }
+
+  return FALSE;
 }
+                         
+
index ee9d48aeb3570d449073c5b88b608416f9c8e2a6..010ebfe939fda739b9d7bf42457b15134149e301 100644 (file)
@@ -26,6 +26,8 @@ typedef struct _GtkIconCache GtkIconCache;
 GtkIconCache *_gtk_icon_cache_new_for_path   (const gchar  *path);
 gboolean      _gtk_icon_cache_has_directory  (GtkIconCache *cache,
                                              const gchar  *directory);
+gboolean      _gtk_icon_cache_has_icon       (GtkIconCache *cache,
+                                             const gchar  *icon_name);
 void         _gtk_icon_cache_add_icons      (GtkIconCache *cache,
                                              const gchar  *directory,
                                              GHashTable   *hash_table);
index 7b428bcf9f0d9a658eeb56ffc736cee0631a63b2..1b9e9a69988c06c641ec90f75013c9a788788d1e 100644 (file)
@@ -1322,6 +1322,27 @@ gtk_icon_theme_load_icon (GtkIconTheme         *icon_theme,
   return pixbuf;
 }
 
+typedef struct 
+{
+  const gchar *icon_name;
+  gboolean found;
+} CacheSearch;
+
+static void
+cache_has_icon (gpointer  key,
+               gpointer  value,
+               gpointer  user_data)
+{
+  GtkIconCache *cache = (GtkIconCache *)value;
+  CacheSearch *search = (CacheSearch *)user_data;
+
+  if (!cache || search->found)
+    return;
+
+  if (_gtk_icon_cache_has_icon (cache, search->icon_name))
+    search->found = TRUE;  
+}
+
 /**
  * gtk_icon_theme_has_icon:
  * @icon_theme: a #GtkIconTheme
@@ -1340,6 +1361,8 @@ gtk_icon_theme_has_icon (GtkIconTheme *icon_theme,
                         const char   *icon_name)
 {
   GtkIconThemePrivate *priv;
+  GList *l;
+  CacheSearch search;
 
   g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), FALSE);
   
@@ -1347,6 +1370,27 @@ gtk_icon_theme_has_icon (GtkIconTheme *icon_theme,
   
   ensure_valid_themes (icon_theme);
 
+  search.icon_name = icon_name;
+  search.found = FALSE;
+
+  for (l = priv->themes; l; l = l->next)
+    {
+      IconTheme *theme = (IconTheme *)l->data;
+
+      g_hash_table_foreach (theme->icon_caches, cache_has_icon, &search);
+
+      if (search.found)
+       return TRUE;
+    }
+
+  for (l = priv->unthemed_icons_caches; l; l = l->next)
+    {
+      GtkIconCache *cache = (GtkIconCache *)l->data;
+
+      if (_gtk_icon_cache_has_icon (cache, icon_name))
+       return TRUE;
+    }
+
   if (g_hash_table_lookup_extended (priv->all_icons,
                                    icon_name, NULL, NULL))
     return TRUE;
@@ -1741,9 +1785,9 @@ theme_dir_get_icon_suffix (IconThemeDir *dir,
                                                           dir->subdir);
 
       if (has_icon_file)
-       {
-         *has_icon_file = suffix & HAS_ICON_FILE;
-       }
+       *has_icon_file = suffix & HAS_ICON_FILE;
+
+      suffix = suffix & ~HAS_ICON_FILE;
     }
   else
       suffix = GPOINTER_TO_UINT (g_hash_table_lookup (dir->icons, icon_name));
index e6957cff68cea567b75e9ce1e3a0ad6de0f10cfa..4bf31ec656e705e465ad6dcadbfc132f1078a477 100644 (file)
@@ -81,10 +81,19 @@ typedef struct
 static gboolean
 foreach_remove_func (gpointer key, gpointer value, gpointer user_data)
 {
+  Image *image = (Image *)value;
   GHashTable *files = user_data;
   GList *list;
-  gboolean free_key = FALSE;;
-  
+  gboolean free_key = FALSE;  
+
+  if (image->flags == HAS_ICON_FILE)
+    {
+      g_free (key);
+      g_free (image);
+
+      return TRUE;
+    }
+
   list = g_hash_table_lookup (files, key);
   if (list)
     free_key = TRUE;
@@ -171,7 +180,7 @@ scan_directory (const gchar *base_path,
          image = g_hash_table_lookup (dir_hash, basename);
          if (image)
            image->flags |= flags;
-         else if ((flags & HAS_ICON_FILE) != HAS_ICON_FILE)
+         else
            {
              if (!dir_added) 
                {